package com.zui.webapp.action;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;

import javax.imageio.ImageIO;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.poi.hssf.usermodel.HSSFPatriarch;
import org.apache.poi.hssf.usermodel.HSSFPicture;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.struts2.ServletActionContext;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;

import com.zui.entity.BaseEntity;
import com.zui.entity.product.Image;
import com.zui.entity.product.Product;
import com.zui.entity.product.ProductFeatureAppl;
import com.zui.entity.product.ProductImage;
import com.zui.manager.ImageManager;
import com.zui.manager.ProductManager;
import com.zui.manager.SessionManager;
import com.zui.util.JQGridList;
import com.zui.util.JqGridPage;
import com.zui.util.Page;
import com.zui.util.UploadedJQFile;

public class ProductAction extends BaseJQGridAction {

	private static final long serialVersionUID = 1L;
	private static final Log log = LogFactory.getLog(ProductAction.class);

	private Product product;
	private ProductImage productImage;
	private Image image;
	private ProductFeatureAppl productFeatureAppl;
	private List<Product> list;
	private JQGridList productFeatureApplList;

	public ProductAction() {
	}

	public ProductAction(ProductManager productManager) {
		this.productManager = productManager;
	}

	private ProductManager productManager;
	public void setProductManager(ProductManager productManager) {
		this.productManager = productManager;
	}
	
	@Autowired
	private SessionManager sessionManager;
	@Autowired
	private ImageManager imageManager;
	/***********************************************************
	 * Business Method start
	 **********************************************************/
	public String index() {
		log.debug("index() method in class ProductAction is executed!");
		return "index";
	}

	public String editNew() {
		log.debug("editNew() method in class ProductAction is executed!");
		product = new Product();
		return "editNew";
	}

	@SuppressWarnings("unchecked")
	public String edit() {
		if (product.getId() == null)
			return "editNew";

		product = (Product) productManager.loadById(Product.class,
				product.getId());
		return "edit";
	}

	public String view() {
		productFeatureAppl = null;
		if (product.getId() == null)
			return "view";
		product = (Product) productManager.loadById(Product.class,
				product.getId());
		return "view";
	}

	public String delete() {
		if (jq.getId() == null)
			return "index";
		productManager.deleteEngtityFlagByIds(Product.class,
				jq.getId().split("\\,"));
		/**
		 * @TODO: success message!
		 */
		return "index";
	}

	public String export() {

		// get the list
		DetachedCriteria criteria = DetachedCriteria.forClass(Product.class);
		if (jq != null && jqFilters != null) {
			jq.setGroupCriteria(criteria, jqFilters);
		}
		criteria.add(Restrictions.eq("isDeleted", BaseEntity.FLAG_N));
		log.debug("productJsonList() method in class ProductAction is executed!");
		list = productManager.findByCriteriaForJQGrid(criteria,
				jq == null ? jq = new JqGridPage() : jq);

		super.setFileNameExported("Product List Exported");

		// create the workbook
		// ExcelService excel = new ExcelServiceImpl();
		HSSFWorkbook wb = this.getWorkbook(list);

		// output workbook to excelstream
		// excelStream = excel.getExcelInputStream("lml.sf.pojo.V_SF_STUINFO",
		// list, "收费学生信息导出Excel_Demo",fieldsName);
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		try {
			wb.write(baos);
			baos.flush();
			byte[] aa = baos.toByteArray();
			excelStream = new ByteArrayInputStream(aa, 0, aa.length);
			baos.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return "excel";
	}
	
	public String addHabooItem() {
		if (product.getId() == null) {
			product.setCreatedByUserLogin(super.getCurrentUserName());
			product.setCreatedDate(Calendar.getInstance().getTime());
		}
		product.setLastModifiedByUserLogin(super.getCurrentUserName());
		product.setLastModifiedDate(Calendar.getInstance().getTime());

		if (product.getPrimaryCategory() != null
				&& product.getPrimaryCategory().getId() == null)
			product.setPrimaryCategory(null);

		productManager.saveOrUpdate(product);
		this.addProductImage();
		return SUCCESS;
	}
	public String addProductImage() {
		
    	String relativePath = Image.DEFAULT_IMAGE_RELATIVE_PATH 
    			+ System.getProperty("file.separator")
    			+ "Product" 
    			+ System.getProperty("file.separator") 
    			+ product.getPrimaryCategory().getId();
    	String realPath = ServletActionContext.getServletContext().getRealPath("/") + relativePath;
    	Image image = new Image(uploadedFile, uploadedFileFileName, super.getAppContextPath(),relativePath, realPath);
    	
    	imageManager.addImage(image);
    	product = productManager.loadById(product.getId());
    	
    	ProductImage pi = new ProductImage(image);
    	product.addProductImage(pi);
		// update database
    	productManager.saveOrUpdate(product);
		
		UploadedJQFile uf = new UploadedJQFile(image.getId(),
				uploadedFileFileName,
				image.getOriginalImageFileSize(),
				image.getOriginalImageUrl(),
				image.getSmallImageUrl(),
				super.getAppContextPath() + "/product!deleteProductImage.action?productImage.id="+pi.getId());
		uploadedJQFiles.add(uf);
		
		return "imageAdded";
	}
	public String deleteProductImage() {
		productManager.deleteProductImage(productImage);
		return "imageDeleted";
	}

	public String checkUniqueness() throws Exception {
		DetachedCriteria criteria = DetachedCriteria.forClass(Product.class);
		if (checkedField != null && !"".equals(checkedField.trim())) {

			String methodName = "get"
					+ checkedField.substring(0, 1).toUpperCase()
					+ checkedField.substring(1);
			Method method = Product.class.getMethod(methodName);
			criteria.add(Restrictions.eq(checkedField, method.invoke(product)));
			valid = !productManager.checkExistence(criteria);
		}
		return "jsonValid";
	}

	public String create() {
		log.debug("create() method in class ProductAction is executed!");
		if (product.getId() == null) {
			product.setCreatedByUserLogin(super.getCurrentUserName());
			product.setCreatedDate(Calendar.getInstance().getTime());
			if (product.getPrimaryCategory() != null
					&& product.getPrimaryCategory().getId() == null)
				product.setPrimaryCategory(null);
		} else {
			Product tempProduct = product;
			product = productManager.loadById(product.getId());
			product.setInternalName(tempProduct.getInternalName());
			product.setPrimaryCategory(tempProduct.getPrimaryCategory());
			product.setProductType(tempProduct.getProductType());
			product.setHsCode(tempProduct.getHsCode());
			product.setProductCode(tempProduct.getProductCode());
			product.setBrandName(tempProduct.getBrandName());
			product.setComments(tempProduct.getComments());
			product.setIntroductionDate(tempProduct.getIntroductionDate());
			product.setReleaseDate(tempProduct.getReleaseDate());
			product.setSalesDiscontinuationDate(tempProduct.getSalesDiscontinuationDate());
			product.setSupportDiscontinuationDate(tempProduct.getSupportDiscontinuationDate());
			product.setRequireAmount(tempProduct.getRequireAmount());
			product.setAmountUomType(tempProduct.getAmountUomType());
			product.setDescription(tempProduct.getDescription());
			
			product.setLastModifiedByUserLogin(super.getCurrentUserName());
			product.setLastModifiedDate(Calendar.getInstance().getTime());
		}

		productManager.saveOrUpdate(product);
		return "view";
	}

	public String createAndNew() {
		log.debug("createAndNew() method in class ProductAction is executed!");
		this.create();
		product = null;
		return "editNew";
	}

	/**
	 * TODO: 唯一性校验
	 * 
	 * @return
	 */
	public String addNewFeature() {
		log.debug("addNewFeature() method in class ProductAction is executed!");
		// product.addProductFeatureAppl(productFeatureAppl);
		// productManager.saveOrUpdate(productFeatureAppl);
		// productFeatureAppl =
		// (ProductFeatureAppl)productManager.loadById(ProductFeatureAppl.class,
		// productFeatureAppl.getId());
		// String dd = productFeatureAppl.getFeature().getName();
		return "addNewFeature";
		// StringBuffer sb = new StringBuffer();
		// sb.append("[{");
		// sb.append("id:\"" + productFeatureAppl.getId() + "\",");
		// sb.append("featureApplType:\"" +
		// productFeatureAppl.getProductFeatureApplType().getName() +
		// "\",");
		// sb.append("featureType:\"" +
		// productFeatureAppl.getFeature().getFeatureType().getName() +
		// "\",");
		// sb.append("featureName:\"" +
		// productFeatureAppl.getFeature().getName() + "\",");
		// sb.append("fromDate:\"" + productFeatureAppl.getFromDate() +
		// "\",");
		// sb.append("thruDate:\"" + productFeatureAppl.getThruDate() +
		// "\",");
		// sb.append("sequenceNum:\"" + productFeatureAppl.getSequenceNum() +
		// "\"");
		// sb.append("}]");
		// jsonResult = sb.toString();
		// return "jsonResult";
	}

	public String list() {
		DetachedCriteria criteria = DetachedCriteria.forClass(Product.class);
		if(product!=null && product.getPrimaryCategory()!=null) {
			criteria.add(Restrictions.eq("primaryProductCatalog.id", product.getPrimaryCategory().getId()));	
		}
		
		log.debug("productJsonList() method in class ProductAction is executed!");
		list = productManager.findByCriteria(criteria, page==null?new Page():page);

		return "list";
	}
	
	public String jsonList() {
		DetachedCriteria criteria = DetachedCriteria.forClass(Product.class);
		if (jq != null && jqFilters != null) {
			jq.setGroupCriteria(criteria, jqFilters);
		}
		criteria.add(Restrictions.eq("isDeleted", BaseEntity.FLAG_N));
		log.debug("productJsonList() method in class ProductAction is executed!");
		list = productManager.findByCriteriaForJQGrid(criteria,
				jq == null ? jq = new JqGridPage() : jq);

		// set null for session scope action
		jqFilters = null;
		return "jsonList";
	}

	public void jqgridOper() {
		log.debug("jqgridOper() method in class ProductAction is executed!");
		switch (jq.getOper()) {
		case del:
			delete();
			break;
		case add:
			create();
			break;
		case edit:
			create();
			break;
		default:
			break;
		}
	}

	// Create a workbook from product list
	private HSSFWorkbook getWorkbook(List<Product> list) {
		HSSFWorkbook workbook = new HSSFWorkbook();
		HSSFSheet sheet = workbook.createSheet("Product List");
		String[] columnNames;
		String[] columnMethods;

		// 首先，我们读取list中的第一个元素，根据它来确定工作表的列名，以及输出数据所对应的方法数组
		Product product = list.get(0);
		HSSFRow row = sheet.createRow(0); // 创建第1行，也就是输出表头

		row.createCell(0).setCellValue(new HSSFRichTextString("Product Id"));
		row.createCell(1).setCellValue(
				new HSSFRichTextString("Parent Product Catalog"));
		row.createCell(2).setCellValue(new HSSFRichTextString("Internal Name"));
		row.createCell(3).setCellValue(new HSSFRichTextString("Description"));
		row.createCell(4).setCellValue(new HSSFRichTextString("Image"));

		// 下面是输出各行的数据
		Iterator<Product> it = list.iterator();
		HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
		int i = 0;
		while (it.hasNext()) {
			product = it.next();
			row = sheet.createRow(++i);
			row.createCell(0).setCellValue(product.getProductCode());
			row.createCell(1).setCellValue(
					product.getPrimaryCategory() == null ? "" : product
							.getPrimaryCategory().getName());
			row.createCell(2).setCellValue(product.getInternalName());
			row.createCell(3).setCellValue(product.getDescription());
			// row.createCell(4).setCellValue(product.getc);

			if (product.getProductImages() == null
					|| product.getProductImages().isEmpty())
				continue;

			try {
				Image pi = product.getProductImages().get(0).getImage();
				File image = new File(pi.getDirectory() 
						+ System.getProperty("file.separator") 
						+ pi.getMediumImageFileName());
				insertImage(workbook, patriarch,
						getImageData(ImageIO.read(image)), row.getRowNum(), 4,
						1);
			} catch (MalformedURLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}

		return workbook;
	}

	// 自定义的方法,插入某个图片到指定索引的位置
	private static void insertImage(HSSFWorkbook wb, HSSFPatriarch pa,
			byte[] data, int row, int column, int index) {
		int x1 = index * 250;
		int y1 = 0;
		int x2 = x1 + 255;
		int y2 = 255;
		CreationHelper helper = wb.getCreationHelper();
		 //add a picture shape
	    ClientAnchor anchor = helper.createClientAnchor();
	    //set top-left corner of the picture,
	    //subsequent call of Picture#resize() will operate relative to it
	    anchor.setCol1(column);
	    anchor.setRow1(row);
		HSSFPicture picture = pa.createPicture(anchor,
				wb.addPicture(data, HSSFWorkbook.PICTURE_TYPE_JPEG));
		picture.resize();
	}

	// 从图片里面得到字节数组
	private static byte[] getImageData(BufferedImage bi) {
		try {
			ByteArrayOutputStream bout = new ByteArrayOutputStream();
			ImageIO.write(bi, "PNG", bout);
			return bout.toByteArray();
		} catch (Exception exe) {
			exe.printStackTrace();
			return null;
		}
	}

	/***********************************************************
	 * getters and setters
	 **********************************************************/
	/**
	 * @return the userList
	 */
	public List<Product> getlist() {
		return list;
	}

	/**
	 * @param userList
	 *            the userList to set
	 */
	public void setList(List<Product> list) {
		this.list = list;
	}

	/**
	 * @return the product
	 */
	public Product getProduct() {
		return product;
	}

	/**
	 * @return the list
	 */
	public List<Product> getList() {
		return list;
	}

	/**
	 * @param product
	 *            the product to set
	 */
	public void setProduct(Product product) {
		this.product = product;
	}

	public ProductFeatureAppl getProductFeatureAppl() {
		return productFeatureAppl;
	}

	public void setProductFeatureAppl(
			ProductFeatureAppl productFeatureAppl) {
		this.productFeatureAppl = productFeatureAppl;
	}

	public JQGridList getProductFeatureApplList() {
		return productFeatureApplList;
	}

	public void setProductFeatureApplList(
			JQGridList productFeatureApplList) {
		this.productFeatureApplList = productFeatureApplList;
	}

	public ProductImage getProductImage() {
		return productImage;
	}

	public Image getImage() {
		return image;
	}

	public void setProductImage(ProductImage productImage) {
		this.productImage = productImage;
	}

	public void setImage(Image image) {
		this.image = image;
	}

	
}
